import filecmp
import os


def compare_directories(dir1, dir2, ignore_list=None):
    """
    递归比较两个目录，找出修改、新增和删除的文件

    参数:
        dir1 (str): 第一个目录路径（作为基准）
        dir2 (str): 第二个目录路径（作为比较目标）
        ignore_list (list): 要忽略的文件/目录模式列表

    返回:
        dict: 包含比较结果的字典，包括修改、新增、删除的文件列表
    """
    if ignore_list is None:
        ignore_list = []

    # 初始化结果字典
    results = {
        'added': [],
        'removed': [],
        'modified': [],
        'common_dirs': [],
        'errors': []
    }

    # 检查目录是否存在
    if not os.path.exists(dir1):
        results['errors'].append(f"基准目录不存在: {dir1}")
        return results
    if not os.path.exists(dir2):
        results['errors'].append(f"比较目录不存在: {dir2}")
        return results

    # 检查两个路径是否都是目录或文件
    if os.path.isdir(dir1) != os.path.isdir(dir2):
        results['errors'].append(f"两个目录一个是文件，另一个是文件夹，不能比较")
        return results

    try:
        # 使用dircmp比较目录[3,5](@ref)
        print(f"comparing {dir1} with {dir2}...")
        if os.path.isdir(dir1):  # 比较目录
            cmp = filecmp.dircmp(dir1, dir2, ignore=ignore_list)

            # 找出只在dir2中存在的文件（新增文件）[3,5](@ref)
            results['added'] = cmp.left_only
            # 找出只在dir1中存在的文件（删除文件）[3,5](@ref)
            results['removed'] = cmp.right_only
            if len(results['added']) == 0 and len(results['removed']) == 0:
                # 左右文件数量相同，找出内容不同的文件（修改文件）[3,5](@ref)
                for common_file in cmp.common_files:
                    is_same = filecmp.cmp(os.path.join(dir1, common_file), os.path.join(dir2, common_file), shallow=True)
                    if not is_same:
                        results['modified'].append(common_file)
                        break
            else:  # 左右文件数量已经不同了，没有必要再继续比较了
                results['modified'].append("___ignored_files_count_not_same")

            # 找出共同子目录[5](@ref)
            results['common_dirs'] = cmp.common_dirs

            # 递归比较子目录
            for subdir in cmp.common_dirs:
                subdir1 = os.path.join(dir1, subdir)
                subdir2 = os.path.join(dir2, subdir)
                sub_results = compare_directories(subdir1, subdir2, ignore_list)

                # 合并子目录结果
                for key in ['modified', 'added', 'removed', 'errors']:
                    # 为子目录中的文件添加相对路径前缀
                    if key in ['modified', 'added', 'removed']:
                        prefixed_items = [os.path.join(subdir, item) for item in sub_results[key]]
                        results[key].extend(prefixed_items)
                    else:
                        results[key].extend(sub_results[key])

            return results
        else:  # 比较文件
            is_same = filecmp.cmp(dir1, dir2, shallow=True)
            if not is_same:
                results['modified'].append(dir2)

            return results

    except Exception as e:
        results['errors'].append(f"比较目录时出错: {str(e)}")
        return results


if __name__ == "__main__":
    # dir1 = r"\\diskstation3\10T_01\Fitgirl\Cyberpunk 2077 [FitGirl Repack]"
    # dir2 = r"\\diskstation3\14T_01\fitgirl_10T_01\Cyberpunk 2077 [FitGirl Repack]"
    dir1 = r"E:\___temp\111"
    dir2 = r"E:\___temp\222"
    cmp_result = compare_directories(dir1, dir2)
    print(cmp_result)